package com.dreamchaser.familydevice.shiro.realm;


import com.alibaba.druid.util.StringUtils;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.permission.WildcardPermission;
import org.apache.shiro.util.AntPathMatcher;
import org.apache.shiro.util.PatternMatcher;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * 授权赋予shiro 用户授权的url  checkPermission 等方法 调用验证
 */
public class CustomMatchPermission extends WildcardPermission {

    public CustomMatchPermission(String matchString){
        super(matchString);
    }

    @Override
    public boolean implies(Permission p) {

        // By default only supports comparisons with other WildcardPermissions
        if (!(p instanceof WildcardPermission)) {
            return false;
        }
        CustomMatchPermission wp = (CustomMatchPermission) p;

        List<Set<String>> otherParts = wp.getParts();

        int i = 0;
        // 需要验证的url
        for (Set<String> otherPart : otherParts) {
            int n = 0;
            if (getParts().size() - 1 < i) {
                return true;
            } else {
                Set<String> part = getParts().get(i);
                Iterator<String> itSource = part.iterator();
                while (itSource.hasNext()) {
                    String uri=itSource.next();
                    // shiro权限中的uri
                    String[] resStrArr = uri.split("==");
                    Iterator<String> itUrl = otherPart.iterator();
                    while (itUrl.hasNext()) {
                        String path = itUrl.next();
                        // 需要验证的url
                        String[] pathStrArr = path.split("==");
                        if (
                            // 判断格式是否匹配
                                (pathStrArr.length == 2
                                        && resStrArr.length==2
                                        // 先判断http方法是否一致
                                        && (StringUtils.equalsIgnoreCase(pathStrArr[1], resStrArr[1])||resStrArr[1].equals("*"))
                                        // 判断url是否match
                                        && this.pathMatches(resStrArr[0],pathStrArr[0]))
                                        ||
                                        (pathStrArr.length == 1 && this.pathMatches(resStrArr[0],pathStrArr[0]))
                        ) {
                            ++n;
                            break;
                        }
                    }

                }
                if (n>=otherPart.size()){
                    ++i;
                }else {
                    return false;
                }
            }
        }

            return true;
    }

    private boolean pathMatches(String pattern, String path){
        PatternMatcher pathMatcher = new AntPathMatcher();
        return pathMatcher.matches(pattern, path);
    }


}
